﻿#region Copyright(C)  2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C)  2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	:   FI.Net Application Framework
// COMPONENT ID :   FI.Core.Mvc
// COMPONENT DESC:  Core components integrated with ASP.NET MVC
//
// CREATED DATE/BY:  19 Dec 2018 / Tian Mi
//
// REVISION HISTORY:	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using System;
using System.Web.Mvc;
using System.Web.Routing;
using FI.Core.IoC;

namespace FI.Core.Mvc
{
    /// <summary>
    /// A custom ControllerFactory which leverages iConnect.NET IoC to provide controller.
    /// </summary>
    public class ServiceLocatableControllerFactory : DefaultControllerFactory
    {
        #region Properties
        /// <summary>
        /// Gets the service locator.
        /// </summary>
        public IServiceLocator ServiceLocator { get; private set; }
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ServiceLocatableControllerFactory"/> class.
        /// </summary>
        /// <param name="serviceLocatorName">Name of the service locator.</param>
        public ServiceLocatableControllerFactory(string serviceLocatorName = "")
        {
            if (string.IsNullOrEmpty(serviceLocatorName))
            {
                this.ServiceLocator = ServiceLocatorFactory.GetServiceLocator();
            }
            else
            {
                this.ServiceLocator = ServiceLocatorFactory.GetServiceLocator(serviceLocatorName);
            }
        }
        #endregion

        #region Methods
        /// <summary>
        /// Retrieves the controller instance for the specified request context and controller type.
        /// </summary>
        /// <param name="requestContext">The context of the HTTP request, which includes the HTTP context and route data.</param>
        /// <param name="controllerType">The type of the controller.</param>
        /// <returns>
        /// The controller instance.
        /// </returns>
        /// <exception cref="T:System.Web.HttpException">
        ///   <paramref name="controllerType"/> is null.</exception>
        ///   
        /// <exception cref="T:System.ArgumentException">
        ///   <paramref name="controllerType"/> cannot be assigned.</exception>
        ///   
        /// <exception cref="T:System.InvalidOperationException">An instance of <paramref name="controllerType"/> cannot be created.</exception>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2123:OverrideLinkDemandsShouldBeIdenticalToBase")]
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            if (null == controllerType)
            {
                return null;
            }
            return (IController)this.ServiceLocator.GetService(controllerType);
        }
        #endregion
    }
}
